import axios from "axios";
import { ElMessage, ElLoading } from "element-plus";
import router from "../router";

// 环境配置
const isDev = import.meta.env.MODE === "development";

// 创建axios实例
const service = axios.create({
  baseURL: "http://192.168.100.43:10086/api",
  timeout: 30000, // 增加超时时间到30秒
  // 不设置默认Content-Type，让浏览器根据数据类型自动设置
});

// 请求队列管理
let loadingInstance = null;
let requestCount = 0;

// 显示loading
const showLoading = () => {
  if (requestCount === 0) {
    loadingInstance = ElLoading.service({
      text: "加载中...",
      background: "linear-gradient(135deg, rgba(0, 0, 0, 0.5) 0%, rgba(0, 0, 0, 0.8) 100%)",
    });
  }
  requestCount++;
};

// 隐藏loading
const hideLoading = () => {
  requestCount--;
  if (requestCount <= 0) {
    requestCount = 0;
    if (loadingInstance) {
      loadingInstance.close();
      loadingInstance = null;
    }
  }
};

// 请求拦截器
service.interceptors.request.use(
  (config) => {
    // 显示loading（可通过配置关闭）
    if (config.showLoading !== false) {
      showLoading();
    }

    // 不自动设置Content-Type，让axios根据数据类型自动处理
    // 对于FormData数据，确保不设置Content-Type，让浏览器自动设置正确的multipart/form-data和boundary
    if (config.data instanceof FormData) {
      if (config.headers) {
        delete config.headers["Content-Type"];
      } else {
        config.headers = {};
      }
      // 确保方法是POST或PUT
      if (config.method && ['post', 'put'].indexOf(config.method.toLowerCase()) === -1) {
        console.warn('FormData should be used with POST or PUT method');
      }
    }

    // 添加时间戳防止缓存
    if (config.method === "get") {
      config.params = {
        ...config.params,
        _t: Date.now(),
      };
    }

    // 添加token到请求头
    try {
      const token = localStorage.getItem("token");
      if (token) {
        // 确保token不为空且是有效字符串
        if (typeof token === "string" && token.trim()) {
          config.headers["Authorization"] = `Bearer ${token.trim()}`;
          if (isDev) {
            console.log("✅ Token added to request header");
          }
        } else if (isDev) {
          console.warn("⚠️ Token exists but is not a valid string");
        }
      } else {
        if (isDev) {
          console.log("ℹ️ No token found in localStorage");
        }
      }
    } catch (e) {
      console.error("❌ Error accessing localStorage for token:", e);
    }

    // 开发环境打印请求信息
    if (isDev) {
      console.log("🚀 Request:", {
        url: config.url,
        method: config.method,
        params: config.params,
        data: config.data instanceof FormData ? "[FormData Object]" : config.data,
      });
    }

    return config;
  },
  (error) => {
    hideLoading();
    console.error("请求配置错误：", error);
    ElMessage.error("请求配置错误");
    return Promise.reject(error);
  }
);

// 响应拦截器
service.interceptors.response.use(
  (response) => {
    hideLoading();

    const res = response.data;
    const config = response.config;

    // 开发环境打印响应信息
    if (isDev) {
      console.log("📨 Response:", {
        url: config.url,
        status: response.status,
        data: res,
      });
    }

    // 处理不同的响应状态码
    if (res.code !== undefined) {
      const code = String(res.code);

      // 成功状态码
      if (["200", "0", "success"].includes(code)) {
        return res;
      }

      // 未授权 - 需要重新登录
      if (["401", "403"].includes(code)) {
        ElMessage.error("登录已过期，请重新登录");

        // 清除本地存储
        localStorage.removeItem("token");
        localStorage.removeItem("userInfo");
        localStorage.removeItem("userId");

        // 跳转到登录页
        setTimeout(() => {
          router.push("/").catch(() => {});
        }, 1500);

        return Promise.reject(res);
      }

      // 500错误特殊处理
      if (code === "500") {
        const message =
          res.codeInfo || res.errorMessage || "系统异常，请联系管理员";
        if (config.showError !== false) {
          ElMessage.error(message);
        }
        return Promise.reject(res);
      }

      // 其他错误状态码
      const message = res.msg || res.message || res.codeInfo || "请求失败";
      if (config.showError !== false) {
        ElMessage.error(message);
      }
      return Promise.reject(res);
    }

    // 如果没有code字段，直接返回data
    return res;
  },
  (error) => {
    hideLoading();

    let message = "网络错误，请稍后重试";

    if (error.response) {
      const status = error.response.status;
      switch (status) {
        case 400:
          message = "请求参数错误";
          break;
        case 401:
          message = "未授权访问";
          localStorage.removeItem("token");
          router.push("/").catch(() => {});
          break;
        case 403:
          message = "访问被拒绝";
          break;
        case 404:
          message = "请求的资源不存在";
          break;
        case 500:
          message = "服务器内部错误";
          break;
        case 502:
          message = "网关错误";
          break;
        case 503:
          message = "服务不可用";
          break;
        case 504:
          message = "网关超时";
          break;
        default:
          message = `请求失败 (${status})`;
      }
    } else if (error.code === "ECONNABORTED") {
      message = "请求超时，请稍后重试";
    } else if (error.message.includes("Network Error")) {
      message = "网络连接失败，请检查网络";
    }

    console.error("响应错误：", error);

    // 根据配置决定是否显示错误消息
    if (error.config?.showError !== false) {
      ElMessage.error(message);
    }

    return Promise.reject(error);
  }
);

// HTTP方法封装
const http = {
  /**
   * GET请求
   * @param {string} url 请求地址
   * @param {object} params 请求参数
   * @param {object} config 额外配置
   */
  get(url, params = {}, config = {}) {
    return service.get(url, {
      params,
      ...config,
    });
  },

  /**
   * POST请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 额外配置
   */
  post(url, data = {}, config = {}) {
    return service.post(url, data, config);
  },

  /**
   * PUT请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 额外配置
   */
  put(url, data = {}, config = {}) {
    return service.put(url, data, config);
  },

  /**
   * DELETE请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 额外配置
   */
  delete(url, data = {}, config = {}) {
    return service.delete(url, {
      data,
      ...config,
    });
  },

  /**
   * PATCH请求
   * @param {string} url 请求地址
   * @param {object} data 请求数据
   * @param {object} config 额外配置
   */
  patch(url, data = {}, config = {}) {
    return service.patch(url, data, config);
  },

  /**
   * 文件上传
   * @param {object} options 上传选项
   * @param {string} options.url 上传地址
   * @param {File} options.file 文件对象
   * @param {string} options.name 文件字段名，默认'file'
   * @param {object} options.formData 额外的表单数据
   * @param {function} options.onProgress 上传进度回调
   * @param {object} options.config 额外配置
   */
  upload(options) {
    const {
      url,
      file,
      name = "file",
      formData = {},
      onProgress,
      config = {},
    } = options;

    const data = new FormData();

    // 添加文件
    if (file) {
      data.append(name, file);
    }

    // 添加其他表单数据
    Object.keys(formData).forEach((key) => {
      data.append(key, formData[key]);
    });

    return service.post(url, data, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
      onUploadProgress: onProgress,
      ...config,
    });
  },

  /**
   * 多文件上传
   * @param {object} options 上传选项
   * @param {string} options.url 上传地址
   * @param {File[]} options.files 文件数组
   * @param {string} options.name 文件字段名，默认'files'
   * @param {object} options.formData 额外的表单数据
   * @param {function} options.onProgress 上传进度回调
   * @param {object} options.config 额外配置
   */
  uploadMultiple(options) {
    const {
      url,
      files,
      name = "files",
      formData = {},
      onProgress,
      config = {},
    } = options;

    const data = new FormData();

    // 添加多个文件
    if (files && files.length > 0) {
      files.forEach((file) => {
        data.append(name, file);
      });
    }

    // 添加其他表单数据
    Object.keys(formData).forEach((key) => {
      data.append(key, formData[key]);
    });

    return service.post(url, data, {
      headers: {
        "Content-Type": "multipart/form-data",
      },
      onUploadProgress: onProgress,
      ...config,
    });
  },

  /**
   * 下载文件
   * @param {string} url 下载地址
   * @param {string} filename 文件名
   * @param {object} params 请求参数
   * @param {object} config 额外配置
   */
  download(url, filename, params = {}, config = {}) {
    return service
      .get(url, {
        params,
        responseType: "blob",
        showLoading: true,
        ...config,
      })
      .then((response) => {
        const blob = new Blob([response.data]);
        const downloadUrl = window.URL.createObjectURL(blob);
        const link = document.createElement("a");
        link.href = downloadUrl;
        link.download = filename || "download";
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        window.URL.revokeObjectURL(downloadUrl);
        return response;
      });
  },

  /**
   * 取消请求的token
   */
  CancelToken: axios.CancelToken,

  /**
   * 判断是否为取消请求的错误
   */
  isCancel: axios.isCancel,
};

export default http;
